﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Collections;
using System.Data;
using System.Threading;
using System.Runtime.CompilerServices;

using Castle.Core.Logging;

using InfoGenerateSystem.Domain;
using InfoGenerateSystem.Service.Interfaces;
using InfoGenerateSystem.Component;
using InfoGenerateSystem.Persistence.IDao;
using InfoGenerateSystem.Core.Utils;

namespace InfoGenerateSystem.Service.Implements
{
    /// <summary>
    /// 表图生成服务类
    /// 
    /// 创建人:     王昊
    /// 创建时间:   2009-04-28
    /// 
    /// </summary>
    public class DataSetToImage : AbstractConfigService, IDataSetToImage
    {
        private IGenericDao _dao = ServiceHelper.GetService(typeof(IGenericDao)) as IGenericDao;
        private ILogger _log = ServiceHelper.GetService(typeof(ILogger)) as ILogger;

        DataSetToImageExporter exp;

        public static Int32 threadCount = 0;

        public Int32 ThreadCount
        {
            get { return DataSetToImage.threadCount; }
        }

        public void GoExportImage()
        {
            exp = new DataSetToImageExporter();

            ExportSecurityImages();
            ExportAccountImages();
        }

        public void ExportAccountImages()
        {
            IList<TblbLabel> labelList = _dao.Query<TblbLabel>("TblbLabel.FindAllAccountPicLabels", null);

            DataTable accountTable = _dao.QueryForTable("TblbAccountGraphy.FindAll", null).Tables[0];

            String configFileName = Directory + ConfigFilePath;
            ExportImageConfig eic = ConfigLoader.LoadExportImageConfig(configFileName);
            Int32 imagePercent = eic.ImagePercent;

            ExcelToDatabase.threadCount += labelList.Count;

            foreach (TblbLabel lbl in labelList)
            {
                //Thread ta = new Thread(new ThreadStart(delegate()
                //{
                if (lbl.LABELTYPEID == 15 || lbl.LABELTYPEID == 16)
                {
                    InsertAccountGraphy(accountTable, lbl.SECID, lbl.NAME, imagePercent);
                }
                //}));
                //ta.Start();
            }
        }

        public void ExportSecurityImages()
        {
            //IList<TblbLabel> labelList = GetLabelList(Directory, ConfigFilePath);
            IList<TblbLabel> labelList = _dao.Query<TblbLabel>("TblbLabel.FindAllSecurityPicLabels", null);

            DataTable stockTable = _dao.QueryForTable("SecurityInfo.FindAllStockForSnag", null).Tables[0];
            DataTable fundTable = _dao.QueryForTable("SecurityInfo.FindAllFundForSnag", null).Tables[0];
            //DataTable stockTable = _dao.QueryForTable("SecurityInfo.FindTestStockForSnag", null).Tables[0];
            //DataTable fundTable = _dao.QueryForTable("SecurityInfo.FindTestFundForSnag", null).Tables[0];
            DataTable warrantTable = _dao.QueryForTable("SecurityInfo.FindAllWarrantForSnag", null).Tables[0];
            DataTable bondTable = _dao.QueryForTable("SecurityInfo.FindAllBondForSnag", null).Tables[0];

            String configFileName = Directory + ConfigFilePath;
            ExportImageConfig eic = ConfigLoader.LoadExportImageConfig(configFileName);
            Int32 imagePercent = eic.ImagePercent;

            ExcelToDatabase.threadCount += labelList.Count;

            foreach (TblbLabel lbl in labelList)
            {
                //Thread ta = new Thread(new ThreadStart(delegate()
                //{
                if (lbl.LABELTYPEID == 20)
                {
                    InsertSecurityGraphy(stockTable, lbl.SECID, lbl.NAME, imagePercent);
                }
                else if (lbl.LABELTYPEID == 21)
                {
                    InsertSecurityGraphy(fundTable, lbl.SECID, lbl.NAME, imagePercent);
                }
                else if (lbl.LABELTYPEID == 22)
                {
                    InsertSecurityGraphy(warrantTable, lbl.SECID, lbl.NAME, imagePercent);
                }
                else if (lbl.LABELTYPEID == 23)
                {
                    InsertSecurityGraphy(bondTable, lbl.SECID, lbl.NAME, imagePercent);
                }
                //}));
                //ta.Start();
            }
        }

        //[MethodImpl(MethodImplOptions.Synchronized)]
        private void InsertAccountGraphy(DataTable accountTable, Int64 labelID, String labelName, Int32 imagePercent)
        {
            try
            {
                foreach (DataRow accountInfo in accountTable.Rows)
                {
                    Int64 accountCode = 0;
                    try
                    {
                        accountCode = Convert.ToInt64(accountInfo["ACCOUNTCODE"]);

                        TblbLabelParam labelParam = _dao.Find("TblbLabelParam.FindByLABELID", labelID) as TblbLabelParam;

                        IList<TblbLabelCase> lblCaseList = _dao.Query<TblbLabelCase>("TblbLabelCase.FindByLABELID", labelID);
                        foreach (TblbLabelCase lblCase in lblCaseList)
                        {
                            String procedureName = lblCase.SQLSTR;
                            if (!procedureName.StartsWith("EXEC", StringComparison.OrdinalIgnoreCase))
                            {
                                procedureName = "EXEC " + procedureName;
                            }
                            if (procedureName.Contains("@"))
                            {
                                procedureName = procedureName.Substring(0, procedureName.IndexOf('@'));
                            }

                            Hashtable htParams = new Hashtable();
                            htParams["labelID"] = labelID;
                            htParams["procedureName"] = procedureName;

                            if (accountCode != 0)
                            {
                                htParams["ACCOUNTCODE"] = accountCode;
                            }

                            DataSet dsSource = _dao.QueryForTable("SnagDataProcedure.GetDataByProcedureName", htParams);
                            if (dsSource.Tables[0].Columns.Contains("LABELID"))
                            {
                                dsSource.Tables[0].Columns.Remove("LABELID");
                            }

                            dsSource.Tables[0].Rows.Add(dsSource.Tables[0].NewRow());

                            String title = accountCode + "-" + labelID + "-" + lblCase.SECID.ToString() + "-" + DateTime.Now.ToString("yyyy-MM-dd");
                            String format = ".jpg";
                            String tempDirectory = Directory + "\\Temp\\";
                            String fileName = tempDirectory + title + format;

                            //Image img = exp.DoExportToImage(GetDataSetForImage(labelID, String.Empty, accountCode), imagePercent, fileName);
                            exp.DoExportToImage(dsSource, imagePercent, fileName);

                            //img.Save(Directory + @"\Temp\Snag-" + title + ".jpg", System.Drawing.Imaging.ImageFormat.Jpeg);

                            //MemoryStream imgStream = new MemoryStream();
                            //img.Save(imgStream, ImageFormat.Jpeg);
                            //Byte[] bytes = { };
                            //bytes = imgStream.ToArray();

                            FileStream fs = File.OpenRead(fileName);
                            Byte[] bytes = new Byte[fs.Length];
                            fs.Read(bytes, 0, bytes.Length);
                            fs.Close();

                            TblbAccountGraphyData grph = new TblbAccountGraphyData();
                            grph.LABELID = labelID;
                            grph.FILENAME = title;
                            grph.NR = bytes;
                            grph.ACCOUNTCODE = accountCode;
                            grph.OPERATIONDATE = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd"));
                            grph.LASTEDITDATE = DateTime.Now;
                            _dao.Delete("TblbAccountGraphyData.DeleteOne", grph);
                            _dao.Insert("TblbAccountGraphyData.Insert", grph);

                            //imgStream.Close();
                            //imgStream.Dispose();
                            //exp.CloseImageStream();
                            //System.GC.Collect();

                            File.Delete(fileName);
                            exp.DisposeGrid();
                            //System.GC.Collect();
                        }
                    }
                    catch (Exception ex)
                    {
                        _log.Error(DateTime.Now.ToString());
                        _log.Error(Convert.ToString(labelID + "," + Convert.ToString(accountCode)));
                        _log.Error(ex.Message);
                        _log.Error(ex.StackTrace);

                        continue;
                    }
                }
            }
            finally
            {
                DataSetToImage.threadCount--;
            }
        }

        //[MethodImpl(MethodImplOptions.Synchronized)]
        private void InsertSecurityGraphy(DataTable securityTable, Int64 labelID, String labelName, Int32 imagePercent)
        {
            try
            {
                foreach (DataRow securityInfo in securityTable.Rows)
                {
                    String secuCode = String.Empty;
                    try
                    {
                        secuCode = Convert.ToString(securityInfo["ZQDM"]);
                        String secuName = Convert.ToString(securityInfo["ZQJC"]);
                        Int32 secuType = Convert.ToInt32(securityInfo["STOCKTYPE"]);

                        TblbLabelParam labelParam = _dao.Find("TblbLabelParam.FindByLABELID", labelID) as TblbLabelParam;

                        IList<TblbLabelCase> lblCaseList = _dao.Query<TblbLabelCase>("TblbLabelCase.FindByLABELID", labelID);
                        foreach (TblbLabelCase lblCase in lblCaseList)
                        {
                            String procedureName = lblCase.SQLSTR;
                            if (!procedureName.StartsWith("EXEC", StringComparison.OrdinalIgnoreCase))
                            {
                                procedureName = "EXEC " + procedureName;
                            }
                            if (procedureName.Contains("@"))
                            {
                                procedureName = procedureName.Substring(0, procedureName.IndexOf('@'));
                            }

                            Hashtable htParams = new Hashtable();
                            htParams["labelID"] = labelID;
                            htParams["procedureName"] = procedureName;

                            if (!String.IsNullOrEmpty(secuCode))
                            {
                                htParams["STOCKCODE"] = secuCode;
                            }

                            DataSet dsSource = _dao.QueryForTable("SnagDataProcedure.GetDataByProcedureName", htParams);
                            if (dsSource.Tables[0].Columns.Contains("LABELID"))
                            {
                                dsSource.Tables[0].Columns.Remove("LABELID");
                            }

                            dsSource.Tables[0].Rows.Add(dsSource.Tables[0].NewRow());

                            String title = secuCode + "-" + labelID + "-" + lblCase.SECID.ToString() + "-" + DateTime.Now.ToString("yyyy-MM-dd");
                            String format = ".jpg";
                            String tempDirectory = Directory + "\\Temp\\";
                            String fileName = tempDirectory + title + format;

                            //Image img = exp.DoExportToImage(GetDataSetForImage(labelID, secuCode, 0), imagePercent, fileName);
                            exp.DoExportToImage(dsSource, imagePercent, fileName);

                            //img.Save(Directory + "\\Temp\\Snag-" + title + ".jpg", ImageFormat.Jpeg);

                            //MemoryStream imgStream = new MemoryStream();
                            //img.Save(imgStream, ImageFormat.Jpeg);
                            //Byte[] bytes = { };
                            //bytes = imgStream.ToArray();

                            FileStream fs = File.OpenRead(fileName);
                            Byte[] bytes = new Byte[fs.Length];
                            fs.Read(bytes, 0, bytes.Length);
                            fs.Close();

                            TblbStockIndexesGraphyData grph = new TblbStockIndexesGraphyData();
                            grph.LABELID = labelID;
                            grph.FILENAME = title;
                            grph.NR = bytes;
                            grph.STOCKCODE = secuCode;
                            grph.STOCKNAME = secuName;
                            grph.STOCKTYPE = secuType;
                            grph.OPERATIONDATE = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd"));
                            grph.LASTEDITDATE = DateTime.Now;
                            _dao.Delete("TblbStockIndexesGraphyData.DeleteOne", grph);
                            _dao.Insert("TblbStockIndexesGraphyData.Insert", grph);

                            //imgStream.Close();
                            //imgStream.Dispose();
                            //exp.CloseImageStream();
                            //System.GC.Collect();

                            File.Delete(fileName);
                            exp.DisposeGrid();
                            //System.GC.Collect();
                        }
                    }
                    catch (Exception ex)
                    {
                        _log.Error(DateTime.Now.ToString());
                        _log.Error(Convert.ToString(labelID + "," + secuCode));
                        _log.Error(ex.Message);
                        _log.Error(ex.StackTrace);

                        continue;
                    }
                }
            }
            finally
            {
                DataSetToImage.threadCount--;
            }
        }

        private DataSet GetDataSetForImage(Int64 labelID, String stkCode, Int64 accountCode)
        {
            TblbLabelCase lblCase = _dao.Find("TblbLabelCase.FindByLABELID", labelID) as TblbLabelCase;
            String procedureName = lblCase.SQLSTR;
            if (!procedureName.StartsWith("EXEC", StringComparison.OrdinalIgnoreCase))
            {
                procedureName = "EXEC " + procedureName;
            }
            if (procedureName.Contains("@"))
            {
                procedureName = procedureName.Substring(0, procedureName.IndexOf('@'));
            }

            Hashtable htParams = new Hashtable();
            htParams["labelID"] = labelID;
            htParams["procedureName"] = procedureName;

            if (!String.IsNullOrEmpty(stkCode))
            {
                htParams["STOCKCODE"] = stkCode;
            }
            if (accountCode != 0)
            {
                htParams["ACCOUNTCODE"] = accountCode;
            }

            DataSet dsSource = _dao.QueryForTable("SnagDataProcedure.GetDataByProcedureName", htParams);
            if (dsSource.Tables[0].Columns.Contains("LABELID"))
            {
                dsSource.Tables[0].Columns.Remove("LABELID");
            }

            dsSource.Tables[0].Rows.Add(dsSource.Tables[0].NewRow());

            return dsSource;
        }

        public void DeleteBeforeRecords(DateTime time)
        {
            //_dao.Delete("TblbStockIndexesGraphyData.DeleteBeforeRecords", time);
            //_dao.Delete("TblbAccountGraphyData.DeleteBeforeRecords", time);
        }

        public ExportImageConfig GetExportImageConfig()
        {
            return ConfigLoader.LoadExportImageConfig(Directory + ConfigFilePath);
        }

        public void SaveExportImageConfig(ExportImageConfig eic, IList<TblbLabel> labelList)
        {
            ConfigSaver.SaveExportImageConfig(Directory + ConfigFilePath, eic, labelList);
        }
    }
}